iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0
Odoo

Odoo 部署策略系列 第 5

odoo 依賴套件詳解:打造穩定的 Docker 環境

  • 分享至 

  • xImage
  •  

原本不打算特別寫一篇來講解依賴套件的部分,但在實際操作中踩到了一些問題,經過深入研究後,覺得還是值得分享這段經驗。

這個問題源自於第二篇提到的內容。我最初計畫使用 Poetry 來管理套件,以固定各個 Python 套件的版本,作為解決方案。一開始,我把 Dockerfile 裡面所有 python3- 開頭相關的套件移動到 Poetry 的 pyproject.toml 中,剩下的套件則用 apt 安裝。

基本上這樣的配置運行起來沒有問題,但出現了一個奇怪的情況:在啟動 odoo 時,我一直會看到一個警告訊息:

vobject DeprecationWarning: invalid escape sequence

然而,在使用 Source Install 在我的 WSL(Windows Subsystem for Linux)和官方的 odoo Docker 中,都沒有看到這個警告。

我搜尋後發現這個警告已經被修復了(參考連結),雖然在 vobject 現在最新的釋出版本中還沒合併,但目前對功能也沒有影響。

後續我仔細去比對我的環境和官方的差別,發現我們使用的 Python 版本和 vobject 版本都是一樣的,但只有我的環境會出現這個警告,雖然沒有功能上的影響,但這代表我的 odoo 環境跟官方版本有不同的行為。我認為這在後續的開發中會造成很大的麻煩,而這很可能是因為安裝方式的不同所導致的,這是我非常不希望看到的,可能會花上非常多時間處理莫名的問題,因此前期砸了很多時間來研究解決這個問題。


我前幾天發的文章 分析 Odoo 官方安裝方法:從原始碼、套件管理或 Docker 安裝 中,提到各種安裝方法使用的不同依賴套件,主要分為原始碼安裝和套件安裝。

在原始碼安裝的 debinstall.sh 部分,仔細查看會發現有一個 -l 參數:

if [ "$1" = "-l" -o "$1" = "--list" ]; then
    cmd="echo"

大意上就是把原本會用 apt install 執行的部分替換成 echo,我們可以由此觀察到它會安裝哪些套件。執行後,確實拿到了它從 debian/control 中提取出的列表:

adduser, fonts-dejavu-core, fonts-freefont-ttf, fonts-freefont-otf, fonts-noto-core, fonts-font-awesome, fonts-inconsolata, fonts-roboto-unhinted, gsfonts, libjs-underscore, lsb-base, postgresql-client, python3-babel, python3-chardet, python3-dateutil, python3-decorator, python3-docutils, python3-freezegun, python3-geoip2, python3-jinja2, python3-libsass, python3-lxml-html-clean, python3-lxml, python3-num2words, python3-ofxparse, python3-openssl, python3-passlib, python3-pil, python3-polib, python3-psutil, python3-psycopg2, python3-pydot, python3-pypdf2, python3-qrcode, python3-renderpm, python3-reportlab, python3-requests, python3-rjsmin, python3-stdnum, python3-tz, python3-vobject, python3-werkzeug, python3-xlrd, python3-xlsxwriter, python3-zeep.

原始碼安裝的依賴套件安裝分析基本上就到這裡告一段落。為了更保險,我又去研究了用套件安裝 odoo 時會安裝哪些東西,所以從 odoo 的 nightly server 下載了 odoo_17.0.latest_all.deb 來做分析:

dpkg --info odoo_17.0.latest_all.deb
...
 Pre-Depends: init-system-helpers (>= 1.54~)
 Depends: python3-babel, python3-chardet, python3-cryptography, python3-dateutil, python3-decorator, python3-docutils, python3-geoip2, python3-gevent, python3-greenlet, python3-idna, python3-jinja2, python3-libsass, python3-lxml, python3-markupsafe, python3-num2words, python3-ofxparse, python3-openssl, python3-passlib, python3-pil, python3-polib, python3-psutil, python3-psycopg2, python3-pydot, python3-pypdf2, python3-qrcode, python3-reportlab, python3-requests, python3-rjsmin, python3-serial, python3-stdnum, python3-tz, python3-urllib3, python3-usb, python3-vobject, python3-werkzeug, python3-xlrd, python3-xlsxwriter, python3-xlwt, python3-zeep, python3:any, adduser, fonts-dejavu-core | fonts-freefont-ttf | fonts-freefont-otf | fonts-noto-core, fonts-inconsolata, fonts-font-awesome, fonts-roboto-unhinted, gsfonts, libjs-underscore, lsb-base, postgresql-client, python3-freezegun, python3-renderpm
...

結果一看之下,發現內容微妙地不一樣。從 .deb 得到的套件多了許多,但理論上 .deb 的套件內容也是從 debian/control 這個檔案生成的,想不通為什麼會不同,花了些時間比對 odoo 的發布日期也看不出個所以然。

直到後來又仔細觀察這個 control 檔,才發現 Depends: 裡面有 ${misc:Depends}${python3:Depends} 這兩個看起來像是變數的東西,應該就是差異所在。

既然從 .deb 來的依賴套件比較完整,最終這就是我們上一章 Dockerfile 裡面 apt install odoo 依賴套件列表的來源。


這邊有一個思考點:既然我們確定要以 .debDepends 作為依賴套件列表的來源,能不能再把 python3- 的套件部分移動出去,放到 Poetry 去安裝呢?達到我們原本想要的更精確的版本控制還有檢測衝突等功能。
為此,我寫了一個簡單的腳本,去查看這些 python3- 套件的 apt 依賴:

#!/bin/bash
#
# extract_python_deps.sh
# © 2024 Andrew Shen <wildfootw@hoschoc.com>
#
# Distributed under the same license as odooBundle-Codebase.
#

# Check if a .deb file is provided
if [ $# -eq 0 ]; then
    echo "Usage: $0 <path_to_deb_file>"
    exit 1
fi

DEB_FILE="$1"

# Check if dpkg-deb is available
if ! command -v dpkg-deb &> /dev/null; then
    echo "Error: dpkg-deb is not installed. Please install the dpkg package."
    exit 1
fi

# Check if apt-rdepends is available
if ! command -v apt-rdepends &> /dev/null; then
    echo "Error: apt-rdepends is not installed. Please run: sudo apt-get install apt-rdepends"
    exit 1
fi

# Extract the Depends field from the .deb file
DEPENDS=$(dpkg-deb -I "$DEB_FILE" | grep -E '^ Depends:' | sed 's/^ Depends://' | tr ',' '\n' | sed 's/|.*//' | sed 's/(.*)//' | sed 's/^[ \t]*//' | sed 's/[ \t]*$//')

# Extract packages that start with python3-
PYTHON_PACKAGES=$(echo "$DEPENDS" | grep '^python3-')

if [ -z "$PYTHON_PACKAGES" ]; then
    echo "No python3-related packages found in $DEB_FILE."
    exit 0
fi

echo "Found the following python3-related packages in $DEB_FILE:"
echo "$PYTHON_PACKAGES"
echo ""

# Run apt-rdepends for each package and collect all dependencies
ALL_DEPENDS=()

for pkg in $PYTHON_PACKAGES; do
    echo "Processing dependencies for package $pkg..."
    DEP_LIST=$(apt-rdepends "$pkg" 2>/dev/null | grep -E '^[a-zA-Z0-9-]+$')
    ALL_DEPENDS+=($DEP_LIST)
done

# Remove duplicate package names
UNIQUE_DEPENDS=($(echo "${ALL_DEPENDS[@]}" | tr ' ' '\n' | sort -u))

echo ""
echo "List of all recursive dependencies:"
for dep in "${UNIQUE_DEPENDS[@]}"; do
    echo "$dep"
done

執行:

./extract_python_deps.sh odoo_17.0.latest_all.deb

最後觀察輸出的內容,發現它們的依賴除了更多 python3 套件外,還有很多非 python3 的套件。如果用 Poetry 來管理的話,會缺乏這些東西,而且數量龐大,我如果把它們都列出來再使用 apt 安裝,感覺花費的時間就本末倒置了,所以最後我們還是決定使用 apt 來安裝這些套件就好。


上一篇
從官方 Dockerfile 開始調整:以原始碼安裝取代套件安裝
下一篇
odoo Docker 的自訂啟動:分析官方 entrypoint.sh
系列文
Odoo 部署策略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言